package com.ls.commons.schedule.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;

import com.ls.commons.schedule.quartz.JobFactory;
import com.ls.commons.schedule.quartz.JobSyncFactory;


/**
 * 任务信息
 * @author  sheng.li
 * @version  [版本号, 2015年6月29日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class ScheduleJob implements Serializable{
    public static final String STATUS_RUNNING = "1";
    public static final String STATUS_NOT_RUNNING = "0";
    public static final String CONCURRENT_IS = "1";
    public static final String CONCURRENT_NOT = "0";
    /* job所在分组   */
    private String jobGroup;
    /* job名称   */
    private String jobName;
    /* job描述   */
    private String jobDesc;
    /* 类的产生方式  */
    private String factoryType;
    /* 目标执行类  */
    private String target;
    /* 目标方法  */
    private String method;
    /* 是否同步执行  */
    private String ifSync;
    /**
     * 任务状态 是否启动任务
     */
    private String jobStatus;
    /**
     * 任务执行时调用哪个类的方法 包名+类名
     */
    private String beanClass;
    /**
     * spring bean
     */
    private String springId;
    /**
     * 任务调用的方法名
     */
    private String methodName;
    /* 触发器   */
    private List<ScheduleTrigger> triggers;
    
    /* 其他-参数-属性   */
    private JobDetail jobDetail;
    
    public ScheduleJob() {}
    
    public ScheduleJob(String jobName) {
        this.jobName = jobName;
    }
    
    public ScheduleJob(String jobGroup,String jobName) {
        this.jobGroup = jobGroup;
        this.jobName = jobName;
    }

    public String getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
    
    public String getFactoryType() {
        return factoryType;
    }

    public ScheduleJob setFactory(String factoryType) {
        this.factoryType = factoryType;
        return this;
    }

    public String getTarget() {
        return target;
    }

    public ScheduleJob setTarget(String target) {
        this.target = target;
        return this;
    }

    public String getMethod() {
        return method;
    }

    public ScheduleJob setMethod(String method) {
        this.method = method;
        return this;
    }

    public String isIfSync() {
        return ifSync;
    }

    public ScheduleJob setIfSync(String ifSync) {
        this.ifSync = ifSync;
        return this;
    }
    
    public String getJobDesc() {
        return jobDesc;
    }

    public ScheduleJob setJobDesc(String jobDesc) {
        this.jobDesc = jobDesc;
        return this;
    }
    
    public List<ScheduleTrigger> getTriggers() {
        return triggers;
    }

    public ScheduleJob setTriggers(List<ScheduleTrigger> triggers) {
        this.triggers = triggers;
        return this;
    }
    
    public void addTrigger(ScheduleTrigger trigger) {
        if(this.triggers == null) {
            this.triggers = new ArrayList<ScheduleTrigger>();
        }
        if(trigger.getSj() == null) {
            trigger.setSj(this);
        }
        this.triggers.add(trigger);
    }
    
    public JobKey jobKey() {
        return JobKey.jobKey(this.jobName, this.jobGroup);
    }

    @SuppressWarnings("unchecked")
    public JobDetail jobDetail() {
        if (jobDetail == null) {
            try{
                if(this.factoryType.equals("job")) {
                    jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(target))
                            .withIdentity(this.jobName, this.jobGroup)
                            .build();
                }else {
                    if(StringUtils.isNotBlank(this.ifSync) && this.ifSync.equals("true")) {
                        jobDetail = JobBuilder.newJob(JobSyncFactory.class)
                                .withIdentity(this.jobName, this.jobGroup)
                                .build();
                    }else {
                        jobDetail = JobBuilder.newJob(JobFactory.class)
                                .withIdentity(this.jobName, this.jobGroup)
                                .build();
                    }
                    JobDataMap jobDataMap = jobDetail.getJobDataMap();
                    jobDataMap.put("Job_Param_factoryType", factoryType);
                    jobDataMap.put("Job_Param_target", target);
                    jobDataMap.put("Job_Param_method", method);
                }
            }catch(Exception e) {
                e.printStackTrace();
            }
        }
        return jobDetail;
    }

    /**
     * 传参数给执行的job(key,value)
     * (在job中 通过 context.getMergedJobDataMap().get(key) 获取值)
     */
    public ScheduleJob addJobData(String key, Object value) {
        final JobDetail detail = jobDetail();
        final JobDataMap jobDataMap = detail.getJobDataMap();
        jobDataMap.put(key, value);
        return this;
    }

    /**
     * 传参数给执行的job(Map)
     * (在job中 通过 context.getMergedJobDataMap().get(key) 获取值)
     */
    public ScheduleJob addJobDataMap(Map<String, Object> map) {
        final JobDetail detail = jobDetail();
        final JobDataMap jobDataMap = detail.getJobDataMap();
        jobDataMap.putAll(map);
        return this;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{jobGroup:'").append(jobGroup).append("'");
        sb.append(", jobName:'").append(jobName).append("'");
        sb.append(", jobDesc:'").append(jobDesc).append("'");
        sb.append(", target:'").append(target).append("'");
        sb.append(", triggers:").append(triggers.toString()).append("}");
        return sb.toString();
    }

    public String getJobStatus()
    {
        return jobStatus;
    }

    public void setJobStatus(String jobStatus)
    {
        this.jobStatus = jobStatus;
    }

    public String getBeanClass()
    {
        return beanClass;
    }

    public void setBeanClass(String beanClass)
    {
        this.beanClass = beanClass;
    }

    public String getSpringId()
    {
        return springId;
    }

    public void setSpringId(String springId)
    {
        this.springId = springId;
    }

    public String getMethodName()
    {
        return methodName;
    }

    public void setMethodName(String methodName)
    {
        this.methodName = methodName;
    }

    public JobDetail getJobDetail()
    {
        return jobDetail;
    }

    public void setJobDetail(JobDetail jobDetail)
    {
        this.jobDetail = jobDetail;
    }

    public String getIfSync()
    {
        return ifSync;
    }

    public void setFactoryType(String factoryType)
    {
        this.factoryType = factoryType;
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((jobGroup == null) ? 0 : jobGroup.hashCode());
        result = prime * result + ((jobName == null) ? 0 : jobName.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ScheduleJob other = (ScheduleJob)obj;
        if (jobGroup == null)
        {
            if (other.jobGroup != null)
                return false;
        }
        else if (!jobGroup.equals(other.jobGroup))
            return false;
        if (jobName == null)
        {
            if (other.jobName != null)
                return false;
        }
        else if (!jobName.equals(other.jobName))
            return false;
        return true;
    }
    
}